package org.jeecg.modules.fk.controller;

import java.net.Inet4Address;
import java.util.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.pagehelper.PageInfo;
import com.google.common.base.CaseFormat;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.jeecg.common.api.vo.Result;
import lombok.extern.slf4j.Slf4j;

import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.SqlInjectionUtil;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.config.annotations.OrgPermissionAnnotation;
import org.jeecg.config.util.CurrentOrgInfoUtil;
import org.jeecg.modules.fk.entity.*;
import org.jeecg.modules.fk.entity.dto.AuthOrgCountDTO;
import org.jeecg.modules.fk.entity.req.DjUserAssignRequest;
import org.jeecg.modules.fk.entity.req.SbqcRequest;
import org.jeecg.modules.fk.service.IDjOrgService;
import org.jeecg.modules.fk.service.IDjUserInfoService;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.modules.fk.service.ISysCityService;
import org.jeecg.modules.fk.utils.CheckRoleUtil;
import org.jeecg.modules.qyxx.config.AreaConfigProperties;
import org.jeecg.modules.qyxx.entity.CompanyInfo;
import org.jeecg.modules.qyxx.enumdemo.RedisKeyConstant;
import org.jeecg.modules.qyxx.util.DjLoginUtil;
import org.jeecg.modules.qyxx.util.RedisUtil;
import org.jeecg.modules.system.entity.SysDepart;
import org.jeecg.modules.system.model.DepartIdModel;
import org.jeecg.modules.system.service.ISysDepartService;
import org.jeecg.modules.system.service.ISysUserService;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.jeecg.common.aspect.annotation.AutoLog;

/**
 * @Description: dj_user_org_ext
 * @Author: ZJJ
 * @Date: 2021-05-14
 * @Version: V1.0
 */
@Api(tags = "授权企业接口")
@RestController
@RequestMapping("/dj/djUserInfo")
@Slf4j
public class DjUserInfoController extends JeecgController<DjUserInfo, IDjUserInfoService> {
    @Autowired
    private IDjUserInfoService djUserInfoService;

    @Autowired
    private ISysDepartService sysDepartService;

    @Autowired
    private ISysCityService sysCityService;

    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private IDjOrgService djOrgService;

    @Autowired
    private AreaConfigProperties areaConfigProperties;

    /**
     * 分页列表查询
     *
     * @param djOrg
     * @param pageNo
     * @param pageSize
     * @return
     */
    @AutoLog(value = "授权企业分页列表查询")
    @ApiOperation(value = "授权企业分页列表查询", notes = "授权企业分页列表查询")
    @GetMapping(value = "/list")
    public Result<?> queryPageList(DjOrg djOrg,
                                   @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                   @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                   HttpServletRequest req) {
        //IPage<DjUserInfo> pageList = djUserInfoService.queryPageList(djUserInfo,pageNo,pageSize,req);
        // List<DjUserInfo> djUserInfos = djUserInfoService.listForPage(djUserInfo);
        //排序列
        final String ORDER_COLUMN = "column";
        //排序方式
        final String ORDER_TYPE = "order";
        final String ORDER_TYPE_ASC = "ASC", ORDER_TYPE_DESC = "DESC";
        Map<String, String[]> parameterMap = req.getParameterMap();
        String column = null, order = null;
        if (parameterMap != null && parameterMap.containsKey(ORDER_COLUMN)) {
            column = parameterMap.get(ORDER_COLUMN)[0];
        }
        if (parameterMap != null && parameterMap.containsKey(ORDER_TYPE)) {
            order = parameterMap.get(ORDER_TYPE)[0];
        }
        log.debug("排序规则>>列:" + column + ",排序方式:" + order);
        if (oConvertUtils.isNotEmpty(column) && oConvertUtils.isNotEmpty(order)) {
            //字典字段，去掉字典翻译文本后缀
            if (column.endsWith(CommonConstant.DICT_TEXT_SUFFIX)) {
                column = column.substring(0, column.lastIndexOf(CommonConstant.DICT_TEXT_SUFFIX));
            }
            //SQL注入check
            SqlInjectionUtil.filterContent(column);
            column = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, column);
            if (order.toUpperCase().indexOf(ORDER_TYPE_ASC) >= 0) {
                order = ORDER_TYPE_ASC;
            } else {
                order = ORDER_TYPE_DESC;
            }
        }

        Page<DjOrg> page = new Page<>(pageNo, pageSize);
        /*List<DjOrg> djOrgs = djOrgService.listForPageWithOrder(djOrg, column, order);

        PageInfo<DjOrg> pageInfo = new PageInfo<>(djOrgs);
        page.setRecords(pageInfo.getList());
        page.setCurrent(pageNo);
        page.setTotal(pageInfo.getTotal());
        page.setSize(pageSize);
        Result<Object> result = new Result<>();
        result.setSuccess(true);
        result.setResult(page);
        return result;*/
        djOrgService.page2(page, djOrg, column, order);
        return Result.OK(page);
    }

/*    *//**
     * 小程序电局授权页面
     *
     * @return
     *//*
    @AutoLog(value = "小程序电局授权页面")
    @PostMapping(value = "/appInput")
    public Result<?> appInput(@RequestBody DjCheckBO djCheckBO, HttpServletRequest request) throws Exception {
        DjCheckVO djCheckVO = new DjCheckVO();
        BeanUtils.copyProperties(djCheckVO, djCheckBO);
        djCheckVO.setQddm("jchl");
        djCheckVO.setIp(request.getRemoteAddr());
        DES des = new DES("jsbgn");
        // 调用第三方接口校验用户是否正确
        String userInfo = DjCheckUtil.dy(sid, "00000", des.encrypt("{'body':[" + JSON.toJSONString(djCheckVO) + "]}"));
        System.out.println(userInfo);
        JSONObject body = JSON.parseObject(userInfo).getJSONObject("body");
        if ("0".equals(body.getString("returncode"))) {
            String nsrs = body.getJSONObject("ssoLoginInfo").getString("nsrs");
            List<CompanyInfo> companyInfos = JSON.parseArray(nsrs, CompanyInfo.class);
            Map<String, Object> map = new HashMap<>();
            map.put("companyInfos", companyInfos);
            map.put("yhm", djCheckBO.getYhm());
            map.put("password", djCheckBO.getPassword());
            map.put("saleNetCode", djCheckBO.getSaleNetCode());
            YhxxDTO dto = body.getJSONObject("ssoLoginInfo").getObject("yhxx", YhxxDTO.class);
            map.put("phone", dto.getSjh());
            map.put("realName", dto.getXm());
            return Result.OK(map);
        }
        return Result.error("用户信息输入有误");
    }

    *//**
     * 电局授权页面
     *
     * @return
     *//*
    @AutoLog(value = "电局授权页面")
    @PostMapping(value = "/input")
    public Result<?> input(@RequestBody DjCheckBO djCheckBO) throws Exception {
        DjCheckVO djCheckVO = new DjCheckVO();
        BeanUtils.copyProperties(djCheckVO, djCheckBO);
        djCheckVO.setIp(Inet4Address.getLocalHost().getHostAddress());
        djCheckVO.setQddm("jchl");
        DES des = new DES("jsbgn");
        // 调用第三方接口校验用户是否正确
        String userInfo = DjCheckUtil.dy(sid, "00000", des.encrypt("{'body':[" + JSON.toJSONString(djCheckVO) + "]}"));
        // System.out.println(userInfo);
        JSONObject jsonObject = JSON.parseObject(userInfo);
        JSONObject body = jsonObject.getJSONObject("body");
        // 判断用户是否正确(当为0是为校验成功)
        if ("0".equals(body.getString("returncode"))) {
            JSONObject ssoLoginInfo = body.getJSONObject("ssoLoginInfo");
            YhxxDTO dto = ssoLoginInfo.getObject("yhxx", YhxxDTO.class);
            CompanyInfo djNsrxx = DjLoginUtil.getLoginCompanyInfo(userInfo, djCheckBO.getNsrsbh());
            *//*CheckParameter.nsrsbh = djCheckBO.getNsrsbh();
            CheckParameter.sessionId = *//*
            // SbqcRequest sbqcRequest = new SbqcRequest();
            // RedisUtil.set(RedisKeyConstant.redisKfptSessionKey + djCheckBO.getNsrsbh(), jsonObject.getJSONObject("body").getString("ssoSessionId"));
            // System.out.println(RedisUtil.get(RedisKeyConstant.redisKfptSessionKey + djCheckBO.getNsrsbh()));
            *//*if (djNsrxx != null && djNsrxx.getGszdjxh() != null) {
                sbqcRequest.setDjxh(djNsrxx.getGszdjxh());
                sbqcRequest.setNsrsbh(djCheckBO.getNsrsbh());
                sbqcRequest.setShxydm(djNsrxx.getShxydm());
                String dy = DjCheckUtil.dy("00.CX.QWS.DZSWJCX.cxQyjbxx", "00000", djCheckBO.getNsrsbh(), jsonObject.getJSONObject("body").getString("ssoSessionId"), JSON.toJSONString(sbqcRequest));
                System.out.println("企业基本信息:" + dy);
            }*//*
            // sbqcRequest.setNsrsbh("91440605MA4WRUKH98");
            djUserInfoService.saveDjUserInfo(djCheckBO, dto, djNsrxx);
            return Result.OK();
        }
        return Result.error("授权失败,输入信息有误");
    }*/

    @AutoLog(value = "获取网点信息列表")
    @PostMapping(value = "/getOutletInformation/{id}")
    public Result<?> getOutletInformation(@PathVariable Long id) {
        LambdaQueryWrapper<SysDepart> wrapper = Wrappers.lambdaQuery(SysDepart.class);
        wrapper.eq(SysDepart::getAddressId, id);
        return Result.OK(sysDepartService.list(wrapper));
    }

    @AutoLog(value = "修改网点")
    @PostMapping(value = "/setOutlet")
    public Result<?> setOutlet(@RequestBody DjUserInfo djUserInfo) {
        djUserInfoService.setOutlet(djUserInfo);
        return Result.OK();
    }

    @AutoLog(value = "获取城市列表")
    @PostMapping(value = "/getCityList")
    public Result<?> getOutletInformation() {
        LambdaQueryWrapper<SysCity> wrapper = Wrappers.lambdaQuery(SysCity.class);
        wrapper.eq(SysCity::getParentId, 3);
        return Result.OK(sysCityService.list(wrapper));
    }

    @AutoLog(value = "获取网点列表")
    @ApiOperation(value = "获取网点列表", notes = "获取网点列表")
    @PostMapping(value = "/getOutletList")
    public Result<?> getOutletList() {
        LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        LambdaQueryWrapper<SysDepart> wrapper = Wrappers.lambdaQuery(SysDepart.class);
        Set<String> roleNameListString = sysUserService.getUserRolesSet(loginUser.getUsername());
        // 如果该用户为超级管理员
        if (CheckRoleUtil.checkIsSuper(roleNameListString)) {
            return Result.OK(sysDepartService.list(wrapper));
        }
        //wrapper.likeRight(SysDepart::getOrgCode, "A04A01A01");
        wrapper.likeRight(SysDepart::getOrgCode, loginUser.getOrgCode());
        return Result.OK(sysDepartService.list(wrapper));
    }

    @AutoLog(value = "分配税局客户")
    @PostMapping(value = "/setDjUser2SysUser")
    public Result<?> setDjUser2SysUser(@RequestBody DjUserAssignRequest req) {
        // djUserInfoService.setDjUser2SysUser(djUserAssignRequest);
        djOrgService.setDjUser2SysUser(req);
        return Result.OK();
    }

    @AutoLog(value = "查询税局客户已授权的企业")
    @PostMapping(value = "/getCompanyList")
    public Result<?> getCompanyList(String phone) {
        return Result.OK(djUserInfoService.getCompanyList(phone));
    }

    @AutoLog(value = "查询税局客户已解除授权的企业")
    @PostMapping(value = "/getFailCompanyList")
    public Result<?> getFailCompanyList(String phone) {
        return Result.OK(djUserInfoService.getFailCompanyList(phone));
    }

    @AutoLog(value = "解除企业授权")
    @PostMapping(value = "/deleteCompany")
    public Result<?> deleteCompany(String nsrsbh) {
        djUserInfoService.deleteCompany(nsrsbh);
        return Result.OK();
    }

    @AutoLog(value = "授权企业统计")
    @ApiOperation(value = "授权企业统计", notes = "授权企业统计")
    @PostMapping(value = "/authOrgCount")
    public Result<?> authOrgCount(@RequestBody(required = false) AuthOrgCountDTO dto) {
        return Result.OK(djOrgService.authOrgCount(dto));
    }

    @ApiOperation(value = "根据税号查询授权企业信息", notes = "根据税号查询授权企业信息")
    @PostMapping(value = "/getOrgByOrgShxdym")
    @OrgPermissionAnnotation
    public Result<?> getOrgByOrgShxdym() {
        String shxydm = CurrentOrgInfoUtil.getCurrentOrgShxydm();
        DjOrg djOrg = djOrgService.getByNsrsbhOrShxydm(shxydm);
        if (djOrg == null) {
            return Result.error("根据社会信用代码" + shxydm + "查询不到企业");
        }
        return Result.OK(djOrg);
    }

    @ApiOperation(value = "修改授权企业信息", notes = "修改授权企业信息")
    @PostMapping(value = "/edit")
    @RequiresPermissions({"orgUserSummary:edit"})
    @OrgPermissionAnnotation
    public Result<?> edit(@RequestBody DjOrg djOrg) {
        String shxydm = CurrentOrgInfoUtil.getCurrentOrgShxydm();
        DjOrg djOrgUpd = djOrgService.getById(djOrg.getOrgId());
        if (!shxydm.equals(djOrgUpd.getShxydm())) {
            return Result.error("请求信息有误，请求头的shxydm与修改企业的shxydm不一致");
        }
        djOrgUpd.setSaleNetCode(djOrg.getSaleNetCode());
        djOrgUpd.setSaleNetName(djOrg.getSaleNetName());
        djOrgUpd.setManageUserId(djOrg.getManageUserId());
        djOrgUpd.setCustomerCode(djOrg.getCustomerCode());
        djOrgUpd.setIndustry(djOrg.getIndustry());
        djOrgUpd.setOrgType(djOrg.getOrgType());
        djOrgUpd.setCityCode(djOrg.getCityCode());
        djOrgService.updateById(djOrgUpd);
        return Result.OK("编辑成功!", null);
    }

    /**
     * 导出excel
     *
     * @param djOrg
     * @param req
     */
    @RequestMapping(value = "/exportXls")
    @RequiresPermissions({"orgUserSummary:export"})
    public ModelAndView exportXls(DjOrg djOrg, HttpServletRequest req) {
        //排序列
        final String ORDER_COLUMN = "column";
        //排序方式
        final String ORDER_TYPE = "order";
        final String ORDER_TYPE_ASC = "ASC", ORDER_TYPE_DESC = "DESC";
        Map<String, String[]> parameterMap = req.getParameterMap();
        String column = null, order = null;
        if (parameterMap != null && parameterMap.containsKey(ORDER_COLUMN)) {
            column = parameterMap.get(ORDER_COLUMN)[0];
        }
        if (parameterMap != null && parameterMap.containsKey(ORDER_TYPE)) {
            order = parameterMap.get(ORDER_TYPE)[0];
        }
        log.debug("排序规则>>列:" + column + ",排序方式:" + order);
        if (oConvertUtils.isNotEmpty(column) && oConvertUtils.isNotEmpty(order)) {
            //字典字段，去掉字典翻译文本后缀
            if (column.endsWith(CommonConstant.DICT_TEXT_SUFFIX)) {
                column = column.substring(0, column.lastIndexOf(CommonConstant.DICT_TEXT_SUFFIX));
            }
            //SQL注入check
            SqlInjectionUtil.filterContent(column);
            column = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, column);
            if (order.toUpperCase().indexOf(ORDER_TYPE_ASC) >= 0) {
                order = ORDER_TYPE_ASC;
            } else {
                order = ORDER_TYPE_DESC;
            }
        }

        List<DjOrg> djOrgs = djOrgService.listForPageWithOrder(djOrg, column, order);
        // Step.3 AutoPoi 导出Excel
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        String title = "授权客户列表";
        ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
        //此处设置的filename无效 ,前端会重更新设置一下
        mv.addObject(NormalExcelConstants.FILE_NAME, title);
        mv.addObject(NormalExcelConstants.CLASS, DjOrg.class);
        ExportParams exportParams=new ExportParams(title + "报表", "导出人:" + sysUser.getRealname(), title);
        mv.addObject(NormalExcelConstants.PARAMS,exportParams);
        mv.addObject(NormalExcelConstants.DATA_LIST, djOrgs);
        return mv;
    }

    @ApiOperation(value = "查询城市列表", notes = "查询城市列表")
    @RequestMapping(value = "/getCitys", method = {RequestMethod.POST, RequestMethod.GET})
    public Result<List<AreaConfigProperties.AreaCodeName>> getCitys() {
        return Result.OK(areaConfigProperties.getAreasList());
    }
}
